#ifndef RING_BASIS_EXTENSION_H
#define RING_BASIS_EXTENSION_H
#include <vector>
#include <cstdint>
#include <gmpxx.h>
#include "modular_reduction.h"
#include "ring_poly.h"
#include "ring.h"
#include "utils.h"
/* *
 * @class FastBasisExtender
 * @brief 快速基转换扩展器类。
 *
 * `FastBasisExtender` 用于执行快速的基转换操作，特别是在同态加密算法中对多项式环的操作，支持从P基到Q基的转换。
 */
class FastBasisExtender {
public:
    Ring *ringQ;
    Ring *ringP;
    Poly *polypoolQ;
    Poly *polypoolP;
    FastBasisExtender(Ring *ringQ, Ring *ringP);
    // 拷贝构造函数
    FastBasisExtender(const FastBasisExtender &other) = delete;
    FastBasisExtender &operator = (const FastBasisExtender &other) = delete;
    // 移动构造函数
    FastBasisExtender(FastBasisExtender &&other) = delete;
    FastBasisExtender &operator = (FastBasisExtender &&other) = delete;

    // tmp
    uint64_t *qVec;
    uint64_t *pVec;
    uint64_t **qHatModq;    // [l][i] (phat_i)_l mod p_i
    uint64_t *pHatModp;     // [k] qhat_k mod q_k
    uint64_t **qHatInvModq; // [l][i] (qhat_i)_l^-1 mod q_i
    uint64_t *pHatInvModp;  // [k] phat_k^-1 mod p_k
    uint64_t *pHatInvModp_shoup;
    uint64_t ***qHatModp; // [l] [i] [k]  (phat_i)_l mod q_k
    uint64_t **pHatModq;  // [k][i] qhat_k mod p_i
    uint64_t *PModq;      // [i] qprod mod p_i
    uint64_t *PInvModq;   // [i] qprod mod p_i
    uint64_t *PInvModqShoup;
    uint64_t **QModp;    // [i] qprod mod p_i
    uint64_t **QInvModp; // [i] qprod mod p_i
    uint64_t **qInvModq; // [i][j] p_i^-1 mod p_j

    uint64_t *baseConvPQ2Q;
    float *vArrayP2Q;
    uint64_t *tmpP;
    void BaseConvertQP2Q(int levelQ, int levelP, Poly *p1Q, Poly *p1P, Poly *p2Q);
    void BaseConvertP2Q(int levelQ, int levelP, Poly *p1P, Poly *p2Q);
    uint64_t *PQModq;
    uint64_t BASECONVERT;
};
/* *
 * @class Decomposer
 * @brief 解构器类，用于处理环上的多项式分解。
 *
 * `Decomposer` 类提供了对多项式的解构与分解操作，用于支持同态加密算法中的基础操作。
 */
class Decomposer {
public:
    Ring *ringQ;
    Ring *ringP;
    // 拷贝构造函数
    Decomposer(const Decomposer &other) = delete;
    Decomposer &operator = (const Decomposer &other) = delete;
    // 移动构造函数
    Decomposer(Decomposer &&other) = delete;
    Decomposer &operator = (Decomposer &&other) = delete;
    //    Decomposer(Ring* ringQ, Ring* ringP);
    //    std::vector<uint64_t> Xalpha();
    void DecomposeAndSplit(int levelQ, int levelP, int alpha, int beta, Poly *p0Q, Poly *p1Q, Poly *p1P);
};


#endif // RING_BASIS_EXTENSION_H